package kr.co.redcircle.service.oAuth.model;

import java.util.Enumeration;
import java.util.Hashtable;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.scribe.builder.ServiceBuilder;
import org.scribe.builder.api.Api;
import org.scribe.model.Token;
import org.scribe.model.Verb;
import org.scribe.model.Verifier;
import org.scribe.oauth.OAuthService;


public class SNSModel extends Hashtable<String, String>{

	public static final String VER_10A = "1.0a";
	public static final String VER_20 = "2.0";
	
	private String id;
	private String SNSclass;
	private String ver;
	private SNSAuthInformation authInfo;
	private SNSCommandCollection commandCollection;
	private OAuthService service;
	private Verifier verifier;
	private Token requestToken;
	private boolean firstCheckFlag = true;
	private Token accessToken;
	
	
	public SNSCommandCollection getCommandCollection() {
		return commandCollection;
	}

	public void setCommandCollection(SNSCommandCollection commandCollection) {
		this.commandCollection = commandCollection;
	}
	
	public Verifier getVerifier() {
		return verifier;
	}

	public void setVerifier(Verifier verifier) {
		this.verifier = verifier;
	}

	public String getVer() {
		return ver;
	}

	public void setVer(String ver) {
		this.ver = ver;
	}

	public void setSNSclass(String sNSclass) {
		SNSclass = sNSclass;
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getSNSclass() {
		return SNSclass;
	}

	public void setProcessorclass(String sNSclass) {
		SNSclass = sNSclass;
	}

	public SNSAuthInformation getAuthInfo() {
		return authInfo;
	}

	public void setAuthInfo(SNSAuthInformation authInfo) {
		this.authInfo = authInfo;
	}

	@SuppressWarnings("unchecked")
	public String getAuthorizationUrl() {
		Class<? extends Api> providerClass = null;
		
		try {
			providerClass = (Class<? extends Api>) Class.forName(SNSclass);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		
		ServiceBuilder builder = new ServiceBuilder();
		builder.provider(providerClass);
		builder.apiKey(this.authInfo.getApplication_id());
		if (this.authInfo.getSecret_id() != null) builder.apiSecret(this.authInfo.getSecret_id());
		if (this.authInfo.getCallback_uri() != null) builder.callback(this.authInfo.getCallback_uri());
		if (this.authInfo.getScope() != null) builder.scope(this.authInfo.getScope());
		
		service = builder.build();
		
		if (this.ver.equals(VER_10A)) requestToken = service.getRequestToken();
		String redirectUrl = service.getAuthorizationUrl(requestToken);
		return redirectUrl;
		
	}
	
	public SNSDefaultResult invoke(String command, ISNSCommandParameters params) {

		ICommand snsComm = commandCollection.get(command);
		
		if (snsComm != null){
			if (this.ver.equals(VER_10A)){
			
				if (accessToken == null) accessToken = service.getAccessToken(this.requestToken, verifier); 
				
			}else if (this.ver.equals(VER_20)){
				
				
				
				if (!id.equals("naver.me2day") && accessToken == null){
					accessToken = service.getAccessToken(null, verifier);
				}
				
				System.out.println("accessToken : " + accessToken.getToken());
				
			}

			setupParameters(params);
			
			return (SNSDefaultResult)snsComm.invoke(params);
			
		}else{
			
			System.out.println("not define command.. :  " + command);
		}
		
		return null;
	}

	private void setupParameters(ISNSCommandParameters params) {
		Enumeration<String> keyEnum = this.keys();

		while(keyEnum.hasMoreElements()){
			
			String paramKey = (String)keyEnum.nextElement();
			String paramVal = this.get(paramKey);
/*			System.out.println(paramKey + " :: " + paramVal);
			if (paramKey.equals("template_info")){
				JSONObject templateJson = JSONObject.fromObject(paramVal);
				String templateId = templateJson.getString("tid");
				ITemplate templateObject = this.getTemplate(templateId);
				JSONArray jArray = templateJson.getJSONArray("map");
				String parameterValue = setupMapping(templateObject.getContents(), jArray);
				System.out.println("jArray.toString() : " + jArray.toString());
				System.out.println("templateObject.getContents() : " + templateObject.getContents());
				System.out.println("pv : " + parameterValue);
				((SNSDefaultParameters)params).put(paramKey, parameterValue);
			}else{
			}
*/			((SNSDefaultParameters)params).put(paramKey, paramVal);
			
		}
		
		params.setAccessToken(accessToken);
		params.setService(service); 
	}

	private String setupMapping(String templateContents, JSONArray jArray) {
		String returnString = templateContents;
		int mapSize = jArray.size();
		System.out.println("templateContents : " + templateContents);
		
		for (int i=0; i<mapSize; i++){
			JSONObject jobj = jArray.getJSONObject(i);
			returnString = returnString.replaceAll("<%="+jobj.getString("key")+"=%>", jobj.getString("value"));
			System.out.println("setupMapping.returnString : " + returnString + " :::: " + "<%="+jobj.getString("key")+"=%>" + " ::: " + jobj.getString("value"));
		}
		
		System.out.println("setupMapping.returnString.last : " + returnString);
		
		return returnString;
	}

	private Verb getVerb(String method) {
		if (method.equals("post")){
			return Verb.POST;
		}else if (method.equals("get")){
			return Verb.GET;
		}else if (method.equals("put")){
			return Verb.PUT;
		}else if (method.equals("delete")){
			return Verb.DELETE;
		}
		
		return null;
	}

	@Override
	public String toString() {
		return "SNSModel [id=" + id + ", SNSclass=" + SNSclass + ", ver=" + ver
				+ ", authInfo=" + authInfo + ", commandCollection="
				+ commandCollection + "]";
	}

	public Token getRequestToken(){
		return this.requestToken;
	}

}
